package com.kang.c0c.optimize;

import com.kang.c0c.symbol.FunctionSymbol;
import com.kang.c0c.symbol.NameTable;
import com.kang.c0c.symbol.Symbol;
import com.kang.c0c.symbol.GlobalTable;
import com.kang.c0c.tree.Tree;
import com.kang.c0c.tree.node.FunctionNode;
import com.kang.c0c.util.Context;

public class GlobalRegAssign {
	private Tree tree;
	private GlobalTable globalTable;
	private int MaxGlobal;
	
	public GlobalRegAssign(Context context){
		super();
		tree = Tree.instance(context);
		globalTable = GlobalTable.instance(context);
		MaxGlobal = 3;
	}
		
	public void RegAssign(){
		int i = 0;
		
		NameTable names = globalTable.nameTable;
		initNameTable(names);
		
		int index = 0, len = names.getVarCount();
		while(index < len){
			String key = names.getKey(index);
			Symbol sym = names.get(key);
			sym.addr = new Address();
			sym.addr.setStored(true);
			sym.setPos(-1);
			sym.addr.setStack(0);
			
			index ++;
		}
		
		ActivityAnalyze analyzer = new ActivityAnalyze();
		while(i < tree.size()){
			FunctionNode func = tree.getByName(tree.getFunctionName(i));
			analyzer.analyze(func);
			Map map = new Map();
			map.makeMap(func);
			map.initColorUp();
			map.colorUp(func.getSym().nameTable, MaxGlobal);
			
			i++;
		}
	}
	
	/**
	 * 清理符号表中的常量信息，并且为参数分配栈内地址，初始化局部变量的全局寄存器信息
	 * 
	 * @param names
	 * @param ret
	 */	
	private void initNameTable(NameTable names){
		int index = 0, len = names.size();
		
		int paramBeta = 8;
		
		while(index < len){
			Symbol sym = names.get(names.getKey(index));
			if(Symbol.isConstant(sym)){
				names.remove(index);
				len --;
			}else{
				if(Symbol.isFunc(sym)){
					FunctionSymbol func = (FunctionSymbol) sym;
					initNameTable(func.nameTable);
				}else if(Symbol.isParam(sym)){
					sym.setPos(paramBeta);
					sym.addr = new Address();
					sym.addr.setStack(paramBeta);
					sym.addr.setStored(true);
					paramBeta += 4;
				}else{
					sym.setPos(0);
					sym.addr = new Address();
				}
				
				index++;
			}
		}
	}	
}
